#pragma once

#include <iostream>

#include <string>

#include <vector>

#include <unistd.h>

#include "data.hpp"


extern Cloud::DataManager *_data; // 定义将在 main 函数中

namespace Cloud{
class HotManager
{
public:
    HotManager(); // 构造函数
    bool RunModule(); // 运行热点模块
private:
    int _hot_time; // 热点时间
    std::string _back_dir; // 备份路径
    std::string _pack_dir; // 压缩文件路径
    std::string _pack_suffix; // 压缩文件后缀
    bool HotJudge(const std::string &filename);
};

HotManager::HotManager(){
    // 相当于初始化对应信息 模块化 有冗余嫌疑但不多 :)
    Config *config = Config::GetInstance(); // 获取配置文件实例
    _back_dir = config->GetBackDir();
    _pack_dir = config->GetPackDir();
    _pack_suffix = config->GetPackFileSuffix();
    _hot_time = config->GetHotTime();

    // 防止热点管理模块因不存在目录而目录读取失败
    // 创建目录 (在创建目录 CreateDirectory() 中已经判断过是否为空 直接调用即可 )
    FileUtil bdfu(_back_dir);
    FileUtil pdfu(_pack_dir);

    bdfu.CreateDirectory();
    pdfu.CreateDirectory();

}

bool HotManager::HotJudge(const std::string &filename){
    // 非热点文件返回真 热点文件返回假
    FileUtil tmp(filename);
    time_t last_atime = tmp.LastATime();
    time_t cur_time = time(nullptr);

    if(_hot_time<cur_time-last_atime){
        return true;
    }
    return false;
}

bool HotManager::RunModule(){
    while(true){
        // 1.遍历备份目录 获取所有文件名
        std::vector<std::string> array;
        FileUtil fu(_back_dir); // 一切皆文件  以文件的形式打开目录
        fu.ScanDirectory(&array); // 用于遍历目录 因为该接口是专门为目录所使用
                                  // 对应所获取的 即为真实路径

        // 2. 遍历判断文件是否为非热点文件
        for(auto &it : array){
            if(!HotJudge(it)){
                // 为热点文件 不用理睬
                continue;
            } 
            // 为非热点文件 
            // 需要进行压缩

            // 3. 获取文件的备份信息 GetOneByRealPath 
            BackupInfo info;
            if(!_data->GetOneByRealPath(it,&info)){
                // 有文件但是没有备份信息
                // 说明没有备份信息
                info.NewBackupInfo(it); // 为该文件进行备份
            } 

            // 4. 压缩文件
            FileUtil tmp(it);
            tmp.Compress(info.pack_path);

            // 5. 删除源文件 更新备份信息
            tmp.Remove();
            info.pack_flag = true; // 更新备份信息状态
            _data->Update(info);

        }
        usleep(1000);// 每隔一毫秒
                     // 防止空目录循环过快
                     // 导致过多占用CPU资源
    }
    return true;
}

} // namespace Cloud 
